import React, { useState, useEffect, useCallback } from 'react';
import { AppScreen, GameData, GameSettings } from './types';
import MainMenu from './components/MainMenu';
import CreateGameScreen from './components/CreateGameScreen';
import GameScreen from './components/game/GameScreen';
import SettingsScreen from './components/SettingsScreen';
import { loadSettings, saveSettings, ensureDefaultTestGameExists } from './services/gameSaveService';
import LoadingSpinner from './components/LoadingSpinner';
import InteractiveGuide from './components/InteractiveGuide';

const Toast: React.FC<{ message: string; type: 'success' | 'error'; onClose: () => void }> = ({ message, type, onClose }) => {
  useEffect(() => {
    const timer = setTimeout(onClose, 3000);
    return () => clearTimeout(timer);
  }, [onClose]);

  const bgColor = type === 'success' ? 'bg-green-500' : 'bg-red-500';
  return (
    <div className={`fixed bottom-5 right-5 ${bgColor} text-white p-4 rounded-lg shadow-lg z-[100] text-sm sm:text-base`}>
      {message}
    </div>
  );
};

const ONBOARDING_VERSION_KEY = 'hasCompletedOnboarding_v3';

const App: React.FC = () => {
  const [currentScreen, setCurrentScreen] = useState<AppScreen>(AppScreen.MainMenu);
  const [previousScreenForSettings, setPreviousScreenForSettings] = useState<AppScreen | null>(null);
  const [activeGame, setActiveGame] = useState<GameData | null>(null);
  const [settings, setSettings] = useState<GameSettings | null>(null);
  const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null);

  // Interactive Guide State
  const [guideStep, setGuideStep] = useState(0);
  const [isGuideActive, setIsGuideActive] = useState(false);

  const showToast = useCallback((message: string, type: 'success' | 'error' = 'success') => {
    setToast({ message, type });
  }, []);

  const advanceGuide = useCallback(() => setGuideStep(prev => prev + 1), []);

  const startGuide = useCallback(() => {
    setGuideStep(0);
    setIsGuideActive(true);
  }, []);
  
  const endGuide = useCallback(() => {
    setIsGuideActive(false);
    localStorage.setItem(ONBOARDING_VERSION_KEY, 'true');
  }, []);

  useEffect(() => {
    const initializeApp = async () => {
        await ensureDefaultTestGameExists();
        const loaded = await loadSettings();
        setSettings(loaded);
        
        const hasCompletedOnboarding = localStorage.getItem(ONBOARDING_VERSION_KEY);
        if (!hasCompletedOnboarding) {
            startGuide();
        }

        if (currentScreen === AppScreen.MainMenu) {
            let initialMessages: string[] = [];
            if (!loaded.apiChannels || loaded.apiChannels.length === 0) {
              initialMessages.push("请先在设置中配置至少一个API渠道。");
            } else if (!loaded.modelConfigs || loaded.modelConfigs.length === 0) {
              initialMessages.push("请先在设置中配置至少一个模型。");
            } else if (!loaded.defaultTextModelId) {
              initialMessages.push("请在设置中选择一个默认的文本生成模型以开始游戏。");
            }

            if (initialMessages.length > 0 && !isGuideActive) {
               showToast(initialMessages.join(' '), "error");
            }
        }
    };
    initializeApp();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []); 

  const handleSettingsChange = useCallback((newSettings: GameSettings) => {
    setSettings(newSettings);
    saveSettings(newSettings);
  }, []);

  const loadSavedGame = useCallback((gameData: GameData) => {
    setActiveGame(gameData);
    setCurrentScreen(AppScreen.GameScreen);
    showToast(`游戏 "${gameData.rulebook.gameName}" 已载入！`);
    if (isGuideActive && guideStep < 4) { // Only advance if coming from main menu flow
      advanceGuide();
    }
  }, [showToast, isGuideActive, guideStep, advanceGuide]);
  
  const handleGoToSettings = useCallback((fromScreen: AppScreen) => {
      setPreviousScreenForSettings(fromScreen);
      setCurrentScreen(AppScreen.Settings);
      if (isGuideActive) {
        advanceGuide();
      }
  }, [isGuideActive, advanceGuide]);
  
  const handleBackFromSettings = useCallback(() => {
      const returnScreen = previousScreenForSettings || AppScreen.MainMenu;
      setCurrentScreen(returnScreen);
      setPreviousScreenForSettings(null); // Reset after use
      if (isGuideActive) {
          advanceGuide();
      }
  }, [previousScreenForSettings, isGuideActive, advanceGuide]);
  
  const handleGameCreated = useCallback((gameData: GameData) => {
      setActiveGame(gameData);
      setCurrentScreen(AppScreen.GameScreen);
      if (isGuideActive) {
          advanceGuide();
      }
  }, [isGuideActive, advanceGuide]);

  const handleGameStateUpdate = useCallback((gameData: GameData) => {
    setActiveGame(gameData);
  }, []);

  const renderScreen = () => {
    if (!settings) {
        return (
            <div className="min-h-screen flex flex-col items-center justify-center p-4 bg-gray-900 text-gray-100">
                <LoadingSpinner text="加载应用数据..." />
            </div>
        );
    }

    switch (currentScreen) {
      case AppScreen.MainMenu:
        return <MainMenu 
            setCurrentScreen={(screen) => {
              if (screen === AppScreen.CreateGame && isGuideActive) advanceGuide();
              setCurrentScreen(screen);
            }} 
            loadSavedGame={loadSavedGame} 
            showToast={showToast} 
            onStartGuide={startGuide}
            onGoToSettings={() => handleGoToSettings(AppScreen.MainMenu)}
        />;
      case AppScreen.CreateGame:
        return <CreateGameScreen onGameCreated={handleGameCreated} setCurrentScreen={setCurrentScreen} setActiveGame={setActiveGame} settings={settings} showToast={showToast} />;
      case AppScreen.GameScreen:
        if (activeGame) {
          return <GameScreen 
            key={activeGame.id} // Add key to force re-mount on game change
            initialGameData={activeGame} 
            settings={settings} 
            setCurrentScreen={setCurrentScreen} 
            showToast={showToast} 
            onSettingsChange={handleSettingsChange}
            onGameStateUpdate={handleGameStateUpdate}
            onGoToSettings={() => handleGoToSettings(AppScreen.GameScreen)}
            isGuideActive={isGuideActive}
            onGuideAdvance={advanceGuide}
          />;
        }
        setCurrentScreen(AppScreen.MainMenu);
        return null;
      case AppScreen.Settings:
        return <SettingsScreen 
            setCurrentScreen={setCurrentScreen} 
            onSettingsChange={handleSettingsChange} 
            showToast={showToast}
            onBack={handleBackFromSettings}
            cameFromGame={previousScreenForSettings === AppScreen.GameScreen}
        />;
      default:
        return <MainMenu 
            setCurrentScreen={setCurrentScreen} 
            loadSavedGame={loadSavedGame} 
            showToast={showToast} 
            onStartGuide={startGuide}
            onGoToSettings={() => handleGoToSettings(AppScreen.MainMenu)}
        />;
    }
  };

  return (
    <div className="app-container bg-gray-900 min-h-screen">
      {renderScreen()}
      {toast && <Toast message={toast.message} type={toast.type} onClose={() => setToast(null)} />}
      <InteractiveGuide
        isActive={isGuideActive}
        currentStep={guideStep}
        onNext={advanceGuide}
        onEnd={endGuide}
        currentScreen={currentScreen}
      />
    </div>
  );
};

export default App;
